<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="coinfaces">

        <title>nginx 反向代理和 https</title>

    <link rel="stylesheet" href="../theme/css/style.css">
    <link rel="stylesheet" href="../theme/css/pygments.css">



</head>

<body>
    <div class="content">
<h1>nginx 反向代理和 https</h1>    <p>
        under
            <a href="../tags/apache/">Apache</a>
            <a href="../tags/https/">HTTPS</a>
            <a href="../tags/nginx/">Nginx</a>
    </p>
    <p>
        in <a href="../categories/uncategorized/">Uncategorized</a>
    </p>
    <p>Published: 2019-03-31</p>


    <!-- wp:quote -->

<blockquote>
<p>这篇文章可能有问题，按照这篇文章设置的 wordpress nginx 反向代理在
https 的情况下不可用。</p>
</blockquote>
<!-- /wp:quote -->

<!-- wp:heading -->

<h2>前提</h2>
<!-- /wp:heading -->

<!-- wp:list -->

<ul>
<li>服务器的操作系统是 Debian 9 amd64</li>
<li>服务器上已经安装了 nginx、python-certbot-nginx</li>
<li>域名解析设置为服务器的 IP 地址</li>
</ul>
<!-- /wp:list -->

<!-- wp:heading -->

<h2>配置目标站点</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->

<p>安装 apache2：</p>
<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="highlight"><pre><span></span><code><span class="err">apt-get install apache2</span>
</code></pre></div>


<!-- /wp:code -->

<!-- wp:paragraph -->

<p>修改 apache2 端口配置（文件 /etc/apache2/ports.conf 的 Listen 命令）：</p>
<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="highlight"><pre><span></span><code><span class="err">Listen 127.0.0.1:8001</span>
</code></pre></div>


<!-- /wp:code -->

<!-- wp:paragraph -->

<p>修改 apache2 默认站点文件
/etc/apache2/sites-enabled/000-default.conf，把 VirtualHost 站点改为
127.0.0.1:8001：</p>
<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="highlight"><pre><span></span><code><span class="nt">&lt;VirtualHost</span> <span class="err">*:8001</span><span class="nt">&gt;</span>
  # bla bla ...
<span class="nt">&lt;/VirtualHost&gt;</span>
</code></pre></div>


<!-- /wp:code -->

<!-- wp:paragraph -->

<p>重启 apache2 服务：</p>
<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="highlight"><pre><span></span><code><span class="err">systemctl restart apache2</span>
</code></pre></div>


<!-- /wp:code -->

<!-- wp:paragraph -->

<p>运行一下命令验证配置是否生效：</p>
<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="highlight"><pre><span></span><code><span class="err">netstat -anp | grep apache2</span>
<span class="err">wget -O - http://127.0.0.1:8001</span>
</code></pre></div>


<!-- /wp:code -->

<!-- wp:paragraph -->

<p>参考资料：<a href="https://www.ostechnix.com/how-to-change-apache-ftp-and-ssh-default-port-to-a-custom-port-part-1/">修改 Apache
默认端口</a></p>
<!-- /wp:paragraph -->

<!-- wp:heading -->

<h2>配置 nginx 反向代理</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->

<p>添加 nginx 虚拟站点配置文件
/etc/nginx/sites-enabled/domain.name，内容如下：</p>
<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="highlight"><pre><span></span><code><span class="nt">server</span> <span class="p">{</span>
    <span class="err">listen</span> <span class="err">80</span><span class="p">;</span>

    <span class="err">server_name</span> <span class="err">domain.name</span><span class="p">;</span>

    <span class="err">location</span> <span class="err">/</span> <span class="err">{</span>
        <span class="err">proxy_set_header</span>        <span class="err">Host</span> <span class="err">$host</span><span class="p">;</span>
        <span class="err">proxy_set_header</span>        <span class="err">X-Real-IP</span> <span class="err">$remote_addr</span><span class="p">;</span>
        <span class="err">proxy_set_header</span>        <span class="err">X-Forwarded-For</span> <span class="err">$proxy_add_x_forwarded_for</span><span class="p">;</span>
        <span class="err">proxy_set_header</span>        <span class="err">X-Forwarded-Proto</span> <span class="err">$scheme</span><span class="p">;</span>

        <span class="err">proxy_pass</span>          <span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="mf">127.0.0.1</span><span class="o">:</span><span class="mi">8001</span><span class="p">;</span>
        <span class="err">proxy_read_timeout</span>  <span class="err">90</span><span class="p">;</span>
<span class="err">domain.name</span>
        <span class="err">proxy_redirect</span>      <span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="mf">127.0.0.1</span><span class="o">:</span><span class="mi">8001</span> <span class="n">http</span><span class="o">://</span><span class="n">domain</span><span class="o">.</span><span class="n">name</span><span class="p">;</span>
    <span class="p">}</span>
<span class="err">}</span>
</code></pre></div>


<!-- /wp:code -->

<!-- wp:paragraph -->

<p>重启 nginx 服务：</p>
<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="highlight"><pre><span></span><code><span class="err">systemctl restart nginx</span>
</code></pre></div>


<!-- /wp:code -->

<!-- wp:paragraph -->

<p>在浏览器中访问 http://domain.name 测试配置是否设置成功。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>参考资料：<a href="https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-with-ssl-as-a-reverse-proxy-for-jenkins">为 Jekins 配置 nginx 反向代理和 https
访问</a></p>
<!-- /wp:paragraph -->

<!-- wp:heading -->

<h2>设置 https 访问</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->

<p>运行命令安装 Let's encrypt 的 SSL 证书：</p>
<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="highlight"><pre><span></span><code><span class="err">certbot --nginx -d domain.name</span>
</code></pre></div>


<!-- /wp:code -->

<!-- wp:paragraph -->

<p>certbot 会安装配置 SSL 证书，并且修改 nginx 配置文件，以及设置 http
重定向到 https（可选）。再次在浏览器中访问 http://domain.name
可以看到访问被自动重定向到 https。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>参考资料：<a href="https://codex.wordpress.org/Installing_WordPress">安装
wordpress</a> 的“Install
Certbot and Generate an SSL Certificate”一章</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->

<h2>其它</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->

<p>可以看到，反向代理 SSL 证书的设置都在 nginx 的配置文件中完成，因为 https
连接是由 nginx
提供的，既然用到了反向代理，自然会引出一个问题，如果在同一个 IP
上不同域名的虚拟主机都要使用
https，能否做到呢？答案是肯定的，但要求服务端和客户端同时支持 <a href="https://en.wikipedia.org/wiki/Server_Name_Indication">TLS 的
Server Name
Identification（SNI）扩展</a>。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>在服务器的 shell 中输入命令</p>
<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="highlight"><pre><span></span><code><span class="err">nginx -V</span>
</code></pre></div>


<!-- /wp:code -->

<!-- wp:paragraph -->

<p>如果 nginx 支持 SNI，会看到单独的一行：</p>
<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="highlight"><pre><span></span><code><span class="err">TLS SNI support enabled</span>
</code></pre></div>


<!-- /wp:code -->

<!-- wp:paragraph -->

<p>可见这个扩展的重要性。<a href="https://en.wikipedia.org/wiki/Server_Name_Indication#Support">一些（比较老的）客户端</a>也不支持
SNI。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>nginx 使用 SNI 不需要特别的配置，直接给不同的虚拟主机添加 SSL
证书即可。具体见<a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-multiple-ssl-certificates-on-one-ip-with-nginx-on-ubuntu-12-04">这篇教程</a>。</p>
<!-- /wp:paragraph -->
    </div>
<nav class="nav sidebar">
    <div class="siteinfo">
        <div class="sitename"><a href="..">coinfaces</a></div>
        <div class="tagline">Another Side of Life</div>
    </div>

        <a href="../categories/">categories</a>
        <a href="..">&larr; Home</a>
</nav><footer class="footer">
    <span>
        &copy; jpli &middot;
        under <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA 4.0</a>
    </span>
    |
    <span>
        Powered by:
        <a href="http://blog.getpelican.com/">Pelican</a>
    </span>
</footer></body>
</html>